#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import sys
import argparse
from collections import namedtuple

sys.path.append('classes')

from WSBase import WSBase
from WSOption import WSOption
from WSException import WSException

def pprinttable(rows):
	headers = rows[0]._fields
	lens = []
	for i in range(len(rows[0])):
		lens.append(len(max([x[i] for x in rows] + [headers[i]],key=lambda x:len(str(x)))))
	formats = []
	hformats = []
	for i in range(len(rows[0])):
		if isinstance(rows[0][i], int):
			formats.append("%%%dd" % lens[i])
		else:
			formats.append("%%-%ds" % lens[i])
		hformats.append("%%-%ds" % lens[i])
	pattern = " | ".join(formats)
	hpattern = " | ".join(hformats)
	separator = "-+-".join(['-' * n for n in lens])
	print (hpattern % tuple(headers))
	print (separator)
	for line in rows:
		print (pattern % tuple(line))

def options_print(name, options):
	children_options_tables = []
	Row = namedtuple('Row',['Name', 'Value', 'Required', 'Description'])
	options_table = []
	for option_name in options:
		if isinstance(options[option_name], WSOption):
			options_table.append(
				Row(options[option_name].name,
					str(options[option_name].value),
					str(options[option_name].required),
					options[option_name].description,) )
		elif isinstance(options[option_name], dict):
			children_options_tables.append((option_name, options[option_name]))
	print(name)
	pprinttable(options_table)
	for (option_name, table) in children_options_tables:
		options_print(option_name, table)

def module_console(base, module_name):
	help_row = namedtuple('help_row',['Command', 'Description'])
	module_console_help = [
		help_row('help','help menu'),
		help_row('info','show module information'),
		help_row('options','show module\'s options'),
		help_row('set','set module\'s option'),
		help_row('run','run module'),
		help_row('back','back to web-scout console'),
	 ]
	try:
		module = base.loadModule(module_name)
	except ImportError as e:
		print('Error: Cannot load module ({})'.format(e))
		return -1
	while True:
		try:
			command_line = input('web-scout (' + module_name + ') > ')
			command_args = command_line.split(' ')
			command = command_args.pop(0)
			if command == 'help':
				pprinttable(module_console_help)
			elif command == 'info':
				print(module.help())
			elif command == 'options':
				options_print(module_name, module.options)
			elif command == 'set':
				module_options = module.options
				for option_name in command_args[:-1]:
					if option_name in module_options:
						module_options = module_options[option_name]
					else:
						raise WSException('Unrecognized option')
				module_options.value = command_args[-1]
			elif command == 'run':
				print("Started module work at " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
				module.run()
				while not module.finished():
					try:
						sys.stdout.flush()
					except:
						time.sleep(1)
				print("\nEnded module work at " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
				print("\n" + module.getResult())
			elif command == 'back':
				return 0
			else:
				raise WSException('Unrecognized command')
		except WSException as e:
			print(e)

def main_console():
	help_row = namedtuple('help_row',['Command', 'Description'])
	console_help = [
		help_row('help','help menu'),
		help_row('use','use module'),
		help_row('modules','list all modules'),
		help_row('exit','exit to console'),
		]
	base = WSBase()
	while True:
		command_line = input('web-scout > ')
		command_args = command_line.split(' ')
		command = command_args.pop(0)
		if command == 'help':
			pprinttable(console_help)
		elif command == 'use':
			if len(command_args) == 1:
				module_console(base, command_args[0])
		elif command == 'modules':
			module_row = namedtuple('module_row',['Name'])
			module_table = list(map(lambda x: module_row(x), base.getModulesList()))
			pprinttable(module_table)
		elif command == 'exit':
			return
		else:
			print('Error: Unrecognized command')

def main():
	parser = argparse.ArgumentParser(description='Web-Scout')
	args = parser.parse_args(sys.argv[1:])
	main_console()


if __name__ == "__main__":
	main()